const { Op } = require("sequelize");
const { Menu: db } = require("../models");
const { NotFound, Conflict } = require("http-errors");
const { success } = require("../utils/response");
const { arrayToTree } = require("../utils");

class MenuController {
  // 获取菜单列表
  async getMenus(req, res, next) {
    try {
      const {
        name,
        title,
        createdAt,
        menuType,
        updatedAt,
        pageSize,
        pageNum,
        all,
        pid,
      } = req.query;
      const size = Math.abs(Number(pageSize)) || 15;
      const page = Math.abs(Number(pageNum)) || 1;
      const where = {};
      title &&
        (where["title"] = {
          [Op.like]: `%${title}%`,
        });
      name &&
        (where["name"] = {
          [Op.like]: `%${name}%`,
        });
      menuType &&
        (where["menuType"] = {
          [Op.eq]: menuType,
        });
      createdAt &&
        (where["createdAt"] = {
          [Op.between]: createdAt.split(","),
        });
      updatedAt &&
        (where["updatedAt"] = {
          [Op.between]: updatedAt.split(","),
        });
      const condition = {
        where,
      };
      const menus = await db.findAll(condition);

      const target =
        Object.keys(where).length > 0 && !menuType
          ? menus
          : arrayToTree(menus, pid ? Number(pid) : 0);

      success(
        res,
        "查询成功",
        all
          ? target
          : {
              total: target.length,
              pageSize: size,
              pageNum: page,
              list: target.slice((page - 1) * size, size * page),
            }
      );
    } catch (error) {
      next(error);
    }
  }
  // 获取指定菜单
  async getMenu(req, res, next) {
    try {
      const id = req.params.id;
      const menu = await db.findOne({
        where: { id },
      });
      if (!menu) throw new NotFound("菜单不存在");
      success(res, "查询成功", menu);
    } catch (error) {
      next(error);
    }
  }
  // 添加菜单
  async addMenu(req, res, next) {
    try {
      const data = filterData(req.body);
      await db.create(data);
      success(res, "添加成功");
    } catch (error) {
      next(error);
    }
  }
  // 编辑菜单
  async editMenu(req, res, next) {
    try {
      const id = req.body.id;
      const menu = await db.findOne({
        where: { id },
      });
      if (!menu) throw new Conflict("菜单不存在。");
      const data = filterData(req.body);
      // 更新数据
      console.log(data);
      await menu.update(data);
      success(res, "编辑成功");
    } catch (error) {
      next(error);
    }
  }
  // 删除菜单
  async delMenu(req, res, next) {
    try {
      const ids = req.query.ids
        .split(",")
        .map((id) => Number(id))
        .filter(Boolean);
      await db.destroy({
        where: {
          id: ids,
        },
      });
      success(res, "删除成功");
    } catch (error) {
      next(error);
    }
  }
}

// 数据过滤
function filterData(data) {
  const nowData = {
    pid: data.pid,
    name: data.name,
    menuType: data.menuType,
    title: data.title,
    path: data.path,
    component: data.component,
    redirect: data.redirect,
    icon: data.icon,
    sort: data.sort,
    position: data.position,
    hidden: data.hidden,
    affix: data.affix,
    noTagView: data.noTagView,
    alwaysShow: data.alwaysShow,
    noCache: data.noCache,
  };

  return Object.fromEntries(
    Object.entries(nowData).filter(
      (item) => item[1] !== "" && item[1] !== void 0
    )
  );
}

module.exports = new MenuController();
